// Copyright 2010 Google Inc. All Rights Reserved.

/**
 * @fileoverview Transport.
 *
 * @author monsur@google.com (Monsur Hossain)
 */

goog.provide('googleapis.Transport');


/**
 * @constructor
 */
googleapis.Transport = function() {
};


/**
 * @type {string} ID of the IFRAME element.
 */
googleapis.Transport.FRAME_ID = 'apiproxy';


/**
 * @type {Element} The proxy iframe DOM element.
 * @private
 */
googleapis.Transport.iframe_ = null;


/**
 * @type {boolean} Whether the proxy is ready to serve requests.
 * @private
 */
googleapis.Transport.proxyReady_ = false;


/**
 * @type {Array.<Object>} Any requests that were queued while the proxy was
 *     initializing.
 * @private
 */
googleapis.Transport.queuedRequests_ = [];


/**
 * Creates a hidden, offscreen IFRAME for proxying requests.
 * @private
 */
googleapis.Transport.setupProxyIframe_ = function() {
  if (!googleapis.Transport.iframe_) {
    var relayUrl = googleapis.Config.get()['proxy'];
    relayUrl += '#parent=' + encodeURIComponent(document.location.href);
    // TODO(uidude) Use secure token generator from gadgets
    relayUrl += '&rpctoken=' + Number(new Date());
    var frame = document.createElement('iframe');
    frame.style.width = '1px';
    frame.style.height = '1px';
    frame.style.position = 'absolute';
    frame.style.left = '-100px';
    frame.src = 'about:blank';
    frame.name = googleapis.Transport.FRAME_ID;
    frame.id = googleapis.Transport.FRAME_ID;
    document.body.appendChild(frame);
    frame.src = relayUrl;
    gadgets.rpc.setupReceiver(frame.id);
    googleapis.Transport.iframe_ = frame;
  }
};


/**
 * Send a request to the server.
 * @param {string} rpc RPC method name.
 * @param {Object} requestParams The RPC request.
 * @param {Function} callback The function to call with the response.
 */
googleapis.Transport.sendRequest = function(rpc, requestParams, callback) {
  if (!googleapis.Transport.iframe_) {
    googleapis.Transport.setupProxyIframe_();
  }
  if (googleapis.Transport.proxyReady_) {
    gadgets.rpc.call(googleapis.Transport.FRAME_ID, rpc,
        function(resp) {
          var jsonResp = gadgets.json.parse(resp);
          // Response from ApiServer.makeRequest is an array of objects,
          // [obj1, obj2].
          // We turn it into an object of id:obj pairs, {id1:obj1, id2:obj2}.
          if (rpc == 'makeRequest') {
            var responseMap = {};
            // TOOD(uidude) Handle top level error
            for (var i = 0; i < jsonResp.length; i++) {
              responseMap[jsonResp[i]['id']] = jsonResp[i];
            }
            callback(responseMap);
          } else {
            // For other requests, we can simply return the response as is.
            callback(jsonResp);
          }
        },
        requestParams);
  } else {
    googleapis.Transport.queuedRequests_.push({
        rpc: rpc,
        requestParams: requestParams,
        callback: callback});
  }
};


/**
 * Callback for when the proxy IRAME is ready to send requests
 */
googleapis.Transport.onProxyReady = function() {
  if (!googleapis.Transport.proxyReady_) {
    googleapis.Transport.proxyReady_ = true;
    // TODO(uidude) Possibly batch these:
    for (var i = 0; i < googleapis.Transport.queuedRequests_.length; i++) {
      var req = googleapis.Transport.queuedRequests_[i];
      googleapis.Transport.sendRequest(
          req.rpc, req.requestParams, req.callback);
    }
  }
};
